home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
PHRO.ZIP
/
POLYGONS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-07-21
|
37KB
|
1,210 lines
{ Polygon Fills Source file }
{ PHRO! }
{ Phred/OTM }
{ achalfin@uceng.uc.edu }
{ DO NOT DISTRIBUTE THIS SOURCE FILE }
Unit Polygons;
{$G+}
Interface
Const
MinX = 0;
MinY = 0;
MaxX = 319;
MaxY = 199;
Procedure GouraudClipPolygon(x1, y1, x2, y2, x3, y3, C1, C2, C3, PgSeg : Integer);
Procedure PhongClipPolygon(x1, y1, x2, y2, x3, y3, t1, p1, t2, p2, t3, p3, PgSeg : Integer; EMap : Pointer);
Implementation
Var
EnvMap : Pointer;
Procedure GouraudPoly(X1, Y1, X2, Y2, X3, Y3, C1, C2, C3, PgSeg : Integer);
Var
xTop, yTop : Integer;
xBot, yBot : Integer;
xMid, yMid : Integer;
cTop, cBot, cMid : Integer;
Count : Integer;
xVal1, xStep1 : Integer;
xVal2, xStep2 : Integer;
cVal1, cStep1 : Integer;
DColor : Integer;
crMid : Integer;
xrMid : Integer;
hCount, cVal : Integer;
Begin
Asm
Mov ax,Y1
Mov bx,X1
Mov cx,Y2
Mov dx,X2
Mov si,C1
Mov di,C2
Mov xTop,bx
Mov yTop,ax
Mov xBot,dx
Mov yBot,cx
Mov cTop,si
Mov cBot,di
Cmp ax,cx
Jle @Skip2Top
Mov xTop,dx
Mov yTop,cx
Mov xBot,bx
Mov yBot,ax
Mov cTop,di
Mov cBot,si
@Skip2Top:
Mov ax,Y3
Mov bx,X3
Mov cx,C3
Cmp ax,yTop
Jge @CheckY3Bottom
Mov dx,yTop
Mov yMid,dx
Mov dx,xTop
Mov xMid,dx
Mov dx,cTop
Mov cMid,dx
Mov yTop,ax
Mov xTop,bx
Mov cTop,cx
Jmp @Fini
@CheckY3Bottom:
Cmp ax,yBot
Jle @Y3Mid
Mov dx,yBot
Mov yMid,dx
Mov dx,xBot
Mov xMid,dx
Mov dx,cBot
Mov cMid,dx
Mov yBot,ax
Mov xBot,bx
Mov cBot,cx
Jmp @Fini
@Y3Mid:
Mov yMid,ax
Mov xMid,bx
Mov cMid,cx
@Fini:
End;
If (yBot-yTop) = 0
Then Begin
xrMid := xMid;
crMid := cMid;
End
Else Begin
xrMid := (yMid-yTop)*(xBot-xTop) Div (yBot-yTop) + xTop;
crMid := (yMid-yTop)*(cBot-cTop) Div (yBot-yTop) + cTop;
End;
Asm
Mov es,PgSeg
End;
If xMid < XrMid
Then Begin
DColor := (crMid-cMid) Shl 8 Div (xrMid-xMid+1);
cVal1 := cTop Shl 8;
xVal1 := xTop Shl 6;
xVal2 := xVal1;
xStep1 := (xMid-xTop) Shl 6 Div (yMid-yTop+1);
cStep1 := (cMid-cTop) Shl 8 Div (yMid-yTop+1);
xStep2 := (xBot-xTop) Shl 6 Div (yBot-yTop+1);
For Count := yTop to yMid do
Begin
Asm
Mov bx,Count
Mov dx,bx
Shl bx,6
Add bh,dl
Mov di,bx
Mov ax,Word Ptr [xVal1]
Shr ax,6
Mov cx,Word Ptr [xVal2]
Shr cx,6
Add di,ax
Sub cx,ax
Inc cx
Js @Exit
Mov bx,dColor
Mov ax,cVal1
Shr cx,1
Jnc @SkipSingle
Mov es:[di],ah
Add ax,bx
Inc di
@SkipSingle:
Jcxz @Exit
@Looper:
Mov dl,ah
Add ax,bx
Mov dh,ah
Add ax,bx
Mov es:[di],dx
Add di,2
Dec cx
Jnz @Looper
@Exit:
End;
Inc(cVal1, cStep1);
Inc(xVal1, xStep1);
Inc(xVal2, xStep2);
End;
xVal2 := xVal2 - xStep2;
cVal1 := cMid Shl 8;
xVal1 := xMid Shl 6;
xStep1 := (xBot-xMid) Shl 6 Div (yBot-yMid+1);
cStep1 := (cBot-cMid) Shl 8 Div (yBot-yMid+1);
For Count := yMid to yBot do
Begin
Asm
Mov bx,Count
Mov dx,bx
Shl bx,6
Add bh,dl
Mov di,bx
Mov ax,Word Ptr [xVal1]
Shr ax,6
Mov cx,Word Ptr [xVal2]
Shr cx,6
Add di,ax
Sub cx,ax
Inc cx
Js @Exit
Jcxz @Exit
Mov bx,dColor
Mov ax,cVal1
Shr cx,1
Jnc @SkipSingle
Mov es:[di],ah
Add ax,bx
Inc di
@SkipSingle:
Jcxz @Exit
@Looper:
Mov dl,ah
Add ax,bx
Mov dh,ah
Add ax,bx
Mov es:[di],dx
Add di,2
Dec cx
Jnz @Looper
@Exit:
End;
Inc(cVal1, cStep1);
Inc(xVal1, xStep1);
Inc(xVal2, xStep2);
End;
End
Else Begin
DColor := (cMid-crMid) Shl 8 Div (xMid-xrMid+1);
cVal1 := cTop Shl 8;
xVal1 := (xTop) Shl 6;
xVal2 := xVal1;
xStep1 := (xBot-xTop) Shl 6 Div (yBot-yTop+1);
cStep1 := (cBot-cTop) Shl 8 Div (yBot-yTop+1);
xStep2 := (xMid-xTop) Shl 6 Div (yMid-yTop+1);
For Count := yTop to yMid do
Begin
Asm
Mov bx,Count
Mov dx,bx
Shl bx,6
Add bh,dl
Mov di,bx
Mov ax,Word Ptr [xVal1]
Shr ax,6
Mov cx,Word Ptr [xVal2]
Shr cx,6
Add di,ax
Sub cx,ax
Inc cx
Js @Exit
Jcxz @Exit
Mov bx,dColor
Mov ax,cVal1
Shr cx,1
Jnc @SkipSingle
Mov es:[di],ah
Add ax,bx
Inc di
@SkipSingle:
Jcxz @Exit
@Looper:
Mov dl,ah
Add ax,bx
Mov dh,ah
Add ax,bx
Mov es:[di],dx
Add di,2
Dec cx
Jnz @Looper
@Exit:
End;
Inc(cVal1, cStep1);
Inc(xVal1, xStep1);
Inc(xVal2, xStep2);
End;
xVal1 := xVal1 - xStep1;
cVal1 := cVal1 - cStep1;
xVal2 := (xMid) Shl 6;
xStep2 := (xBot-xMid) Shl 6 Div (yBot-yMid+1);
For Count := yMid to yBot do
Begin
Asm
Mov bx,Count
Mov dx,bx
Shl bx,6
Add bh,dl
Mov di,bx
Mov ax,Word Ptr [xVal1]
Shr ax,6
Mov cx,Word Ptr [xVal2]
Shr cx,6
Add di,ax
Sub cx,ax
Inc cx
Js @Exit
Jcxz @Exit
Mov bx,dColor
Mov ax,cVal1
Shr cx,1
Jnc @SkipSingle
Mov es:[di],ah
Add ax,bx
Inc di
@SkipSingle:
Jcxz @Exit
@Looper:
Mov dl,ah
Add ax,bx
Mov dh,ah
Add ax,bx
Mov es:[di],dx
Add di,2
Dec cx
Jnz @Looper
@Exit:
End;
Inc(cVal1, cStep1);
Inc(xVal1, xStep1);
Inc(xVal2, xStep2);
End;
End;
End;
Procedure GouraudClipPolygon(x1, y1, x2, y2, x3, y3, C1, C2, C3, PgSeg : Integer);
Type
tFlatClip = Record
x, y, x1, y1 : Integer;
c, c1 : Integer;
End;
Var
FlatList : Array[0..7] of tFlatClip;
NumVert : Integer;
Count : Integer;
ClipVert : Integer;
V1, V2 : Integer;
Begin
If (((X1 >= MinX) and (X1 <= MaxX)) and ((Y1 >= MinY) and (Y1 <= MaxY)) and
((X2 >= MinX) and (X2 <= MaxX)) and ((Y2 >= MinY) and (Y2 <= MaxY))) and
((X3 >= MinX) and (X3 <= MaxX)) and ((Y3 >= MinY) and (Y3 <= MaxY))
Then Begin
GouraudPoly(X1, Y1, X2, Y2, X3, Y3, C1, C2, C3, PgSeg);
Exit;
End;
FlatList[0].x := X1;
FlatList[0].y := Y1;
FlatList[0].c := C1;
FlatList[1].x := X2;
FlatList[1].y := Y2;
FlatList[1].c := C2;
FlatList[2].x := X3;
FlatList[2].y := Y3;
FlatList[2].c := C3;
NumVert := 3;
ClipVert := 0;
{ Clip against left side }
V1 := NumVert - 1;
For Count := 0 to (NumVert-1) do
Begin
If (FlatList[V1].x >= MinX) and (FlatList[Count].x >= MinX)
Then Begin
FlatList[ClipVert].x1 := FlatList[Count].x;
FlatList[ClipVert].y1 := FlatList[Count].y;
FlatList[ClipVert].c1 := FlatList[Count].c;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].x >= MinX) and (FlatList[Count].x < MinX)
Then Begin
FlatList[ClipVert].x1 := MinX;
FlatList[ClipVert].y1 := (FlatList[Count].y-FlatList[V1].y)*(MinX-FlatList[v1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].y;
FlatList[ClipVert].c1 := (FlatList[Count].c-FlatList[V1].c)*(MinX-FlatList[v1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].c;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].x < MinX) and (FlatList[Count].x >= MinX)
Then Begin
FlatList[ClipVert].x1 := MinX;
FlatList[ClipVert].y1 := (FlatList[Count].y-FlatList[V1].y)*(MinX-FlatList[V1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].y;
FlatList[ClipVert].c1 := (FlatList[Count].c-FlatList[V1].c)*(MinX-FlatList[V1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].c;
ClipVert := ClipVert + 1;
FlatList[ClipVert].x1 := FlatList[Count].x;
FlatList[ClipVert].y1 := FlatList[Count].y;
FlatList[ClipVert].c1 := FlatList[Count].c;
ClipVert := ClipVert + 1;
End;
V1 := Count;
End;
NumVert := ClipVert;
ClipVert := 0;
{ Clip against Right side }
V1 := NumVert - 1;
For Count := 0 to (NumVert-1) do
Begin
If (FlatList[v1].x1 <= MaxX) and (FlatList[Count].x1 <= MaxX)
Then Begin
FlatList[ClipVert].x := FlatList[Count].x1;
FlatList[ClipVert].y := FlatList[Count].y1;
FlatList[ClipVert].c := FlatList[Count].c1;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].x1 <= MaxX) and (FlatList[Count].x1 > MaxX)
Then Begin
FlatList[ClipVert].x := MaxX;
FlatList[ClipVert].y := (FlatList[Count].y1-FlatList[V1].y1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].y1;
FlatList[ClipVert].c := (FlatList[Count].c1-FlatList[V1].c1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].c1;
ClipVert := ClipVert + 1;
End;
If (FlatList[v1].x1 > MaxX) and (FlatList[Count].x1 <= MaxX)
Then Begin
FlatList[ClipVert].x := MaxX;
FlatList[ClipVert].y := (FlatList[Count].y1-FlatList[V1].y1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].y1;
FlatList[ClipVert].c := (FlatList[Count].c1-FlatList[V1].c1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].c1;
ClipVert := ClipVert + 1;
FlatList[ClipVert].x := FlatList[Count].x1;
FlatList[ClipVert].y := FlatList[Count].y1;
FlatList[ClipVert].c := FlatList[Count].c1;
ClipVert := ClipVert + 1;
End;
v1 := Count;
End;
NumVert := ClipVert;
ClipVert := 0;
{ Clip against top edge }
V1 := NumVert - 1;
For Count := 0 to (NumVert-1) do
Begin
If (FlatList[V1].y >= MinY) and (FlatList[Count].y >= MinY)
Then Begin
FlatList[ClipVert].x1 := FlatList[Count].x;
FlatList[ClipVert].y1 := FlatList[Count].y;
FlatList[ClipVert].c1 := FlatList[Count].c;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].y >= MinY) and (FlatList[Count].y < MinY)
Then Begin
FlatList[ClipVert].x1 := (MinY-FlatList[V1].y)*(FlatList[Count].x-FlatList[V1].x)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].x;
FlatList[ClipVert].c1 := (MinY-FlatList[V1].y)*(FlatList[Count].c-FlatList[V1].c)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].c;
FlatList[ClipVert].y1 := MinY;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].y < MinY) and (FlatList[Count].y >= MinY)
Then Begin
FlatList[ClipVert].x1 := (MinY-FlatList[V1].y)*(FlatList[Count].x-FlatList[V1].x)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].x;
FlatList[ClipVert].c1 := (MinY-FlatList[V1].y)*(FlatList[Count].c-FlatList[V1].c)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].c;
FlatList[ClipVert].y1 := MinY;
ClipVert := ClipVert + 1;
FlatList[ClipVert].x1 := FlatList[Count].x;
FlatList[ClipVert].y1 := FlatList[Count].y;
FlatList[ClipVert].c1 := FlatList[Count].c;
ClipVert := ClipVert + 1;
End;
V1 := Count;
End;
NumVert := ClipVert;
ClipVert := 0;
V1 := NumVert - 1;
For Count := 0 to (NumVert-1) do
Begin
If (FlatList[V1].y1 <= MaxY) and (FlatList[Count].y1 <= MaxY)
Then Begin
FlatList[ClipVert].x := FlatList[Count].x1;
FlatList[ClipVert].y := FlatList[Count].y1;
FlatList[ClipVert].c := FlatList[Count].c1;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].y1 <= MaxY) and (FlatList[Count].y1 > MaxY)
Then Begin
FlatList[ClipVert].x := (MaxY-FlatList[V1].y1)*(FlatList[Count].x1-FlatList[V1].x1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].x1;
FlatList[ClipVert].c := (MaxY-FlatList[V1].y1)*(FlatList[Count].c1-FlatList[V1].c1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].c1;
FlatList[ClipVert].y := MaxY;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].y1 > MaxY) and (FlatList[Count].y1 <= MaxY)
Then Begin
FlatList[ClipVert].x := (MaxY-FlatList[V1].y1)*(FlatList[Count].x1-FlatList[V1].x1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].x1;
FlatList[ClipVert].c := (MaxY-FlatList[V1].y1)*(FlatList[Count].c1-FlatList[V1].c1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].c1;
FlatList[ClipVert].y := MaxY;
ClipVert := ClipVert + 1;
FlatList[ClipVert].x := FlatList[Count].x1;
FlatList[ClipVert].y := FlatList[Count].y1;
FlatList[ClipVert].c := FlatList[Count].c1;
ClipVert := ClipVert + 1;
End;
V1 := Count;
End;
NumVert := ClipVert;
V1 := 1;
V2 := 2;
{ Now draw the polygons }
For Count := 0 to (NumVert - 3) do
Begin
GouraudPoly(FlatList[0].x, FlatList[0].y,
FlatList[V1].x, FlatList[V1].y,
FlatList[V2].x, FlatList[V2].y,
FlatList[0].c, FlatList[V1].c,
FlatList[V2].c, PgSeg);
V1 := V2;
V2 := V2 + 1;
End;
End;
Procedure PhongPoly(X1, Y1, X2, Y2, X3, Y3, p1, t1, p2, t2, p3, t3, PgSeg : Integer);
Var
xTop, yTop, pTop, tTop : Integer;
xMid, yMid, pMid, tMid : Integer;
xBot, yBot, pBot, tBot : Integer;
xVal1, xStep1, xVal2, xStep2 : Integer;
tVal1, tStep1 : Integer;
pVal1, pStep1 : Integer;
Count : Integer;
xrMid, prMid, trMid : Integer;
pVal, tVal : Integer;
HCount : Integer;
DPhi, DTheta : Integer;
Segment : Word;
yDiver : Integer;
Begin
If Y1 < Y2
Then Begin
yTop := Y1;
xTop := X1;
pTop := p1;
tTop := t1;
yBot := Y2;
xBot := X2;
pBot := p2;
tBot := t2;
End
Else Begin
yTop := Y2;
xTop := X2;
pTop := p2;
tTop := t2;
yBot := Y1;
xBot := X1;
pBot := p1;
tBot := t1;
End;
If Y3 < yTop
Then Begin
yMid := yTop;
xMid := xTop;
tMid := tTop;
pMid := pTop;
xTop := X3;
yTop := Y3;
pTop := p3;
tTop := t3;
End
Else Begin
If Y3 > yBot
Then Begin
yMid := yBot;
xMid := xBot;
pMid := pBot;
tMid := tBot;
xBot := X3;
yBot := Y3;
pBot := p3;
tBot := t3;
End
Else Begin
yMid := Y3;
xMid := X3;
pMid := p3;
tMid := t3;
End;
End;
If yBot-yTop = 0 Then Exit;
Segment := PgSeg;
yDiver := (yMid-yTop) Shl 8 Div (yBot-yTop);
Asm
Mov ax,xBot
Sub ax,xTop
Mov bx,yDiver
IMul bx
Sar ax,8
Add ax,xTop
Mov xrMid,ax
Mov ax,pBot
Sub ax,pTop
IMul bx
Sar ax,8
Add ax,pTop
Mov prMid,ax
Mov ax,tBot
Sub ax,tTop
IMul bx
Sar ax,8
Add ax,tTop
Mov trMid,ax
End;
{ xrMid := (yMid-yTop)*(xBot-xTop) Div (yBot-yTop) + xTop;
prMid := (yMid-yTop)*(pBot-pTop) Div (yBot-yTop) + pTop;
trMid := (yMid-yTop)*(tBot-tTop) Div (yBot-yTop) + tTop;
}
If xMid < xrMid
Then Begin { 2 edges are on the left side }
DPhi := (prMid-pMid) Shl 8 Div (xrMid-xMid+1);
DTheta := (trMid-tMid) Shl 8 Div (xrMid-xMid+1);
xVal1 := xTop Shl 6;
xVal2 := xVal1;
tVal1 := tTop Shl 8;
pVal1 := pTop Shl 8;
xStep1 := (xMid-xTop) Shl 6 Div (yMid-yTop+1);
tStep1 := (tMid-tTop) Shl 8 Div (yMid-yTop+1);
pStep1 := (pMid-pTop) Shl 8 Div (yMid-yTop+1);
xStep2 := (xBot-xTop) Shl 6 Div (yBot-yTop+1);
For Count := yTop to yMid do
Begin
{ ***** HLine *****}
Asm
Mov ax,Segment
Mov es,ax
Mov ax,xVal1
Shr ax,6
Mov cx,xVal2
Shr cx,6
Sub cx,ax
Inc cx
Js @Exit
Jcxz @Exit
Mov bx,Count
Mov dx,bx
Shl bx,6
Add bh,dl
Add bx,ax
Mov di,bx
Mov ax,pVal1
Mov si,dPhi
Mov dx,tVal1
Push bp
Mov bp,dTheta
Push ds
Lds bx,EnvMap
Shr cx,1
Jnc @SkipSingle
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
@SkipSingle:
Xor ch,ch
Jcxz @SkipLoop
@Looper:
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
Dec cl
Jnz @Looper
@SkipLoop:
Pop ds
Pop bp
@Exit:
End;
{ ***** End HLine ***** }
xVal1 := xVal1 + xStep1;
xVal2 := xVal2 + xStep2;
pVal1 := pVal1 + pStep1;
tVal1 := tVal1 + tStep1;
End;
xVal2 := xVal2 - xStep2;
tVal1 := tMid Shl 8;
pVal1 := pMid Shl 8;
xVal1 := xMid Shl 6;
tStep1 := (tBot-tMid) Shl 8 Div (yBot-yMid+1);
pStep1 := (pBot-pMid) Shl 8 Div (yBot-yMid+1);
xStep1 := (xBot-xMid) Shl 6 Div (yBot-yMid+1);
For Count := yMid to yBot do
Begin
{ ***** HLine *****}
Asm
Mov ax,Segment
Mov es,ax
Mov ax,xVal1
Shr ax,6
Mov cx,xVal2
Shr cx,6
Sub cx,ax
Inc cx
Js @Exit
Jcxz @Exit
Mov bx,Count
Mov dx,bx
Shl bx,6
Add bh,dl
Add bx,ax
Mov di,bx
Mov ax,pVal1
Mov si,dPhi
Mov dx,tVal1
Push bp
Mov bp,dTheta
Push ds
Lds bx,EnvMap
Shr cx,1
Jnc @SkipSingle
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
@SkipSingle:
Xor ch,ch
Jcxz @SkipLoop
@Looper:
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
Dec cl
Jnz @Looper
@SkipLoop:
Pop ds
Pop bp
@Exit:
End;
{ ***** End HLine ***** }
xVal1 := xVal1 + xStep1;
xVal2 := xVal2 + xStep2;
pVal1 := pVal1 + pStep1;
tVal1 := tVal1 + tStep1;
End;
End
Else Begin { Long Edge on the left side }
DPhi := (pMid-prMid) Shl 8 Div (xMid-xrMid+1);
DTheta := (tMid-trMid) Shl 8 Div (xMid-xrMid+1);
xVal1 := xTop Shl 6;
tVal1 := tTop Shl 8;
pVal1 := pTop Shl 8;
xVal2 := xVal1;
xStep1 := (xBot-xTop) Shl 6 Div (yBot-yTop+1);
tStep1 := (tBot-tTop) Shl 8 Div (yBot-yTop+1);
pStep1 := (pBot-pTop) Shl 8 Div (yBot-yTop+1);
xStep2 := (xMid-xTop) Shl 6 Div (yMid-yTop+1);
For Count := yTop to yMid do
Begin
{ ***** HLine *****}
Asm
Mov ax,Segment
Mov es,ax
Mov ax,xVal1
Shr ax,6
Mov cx,xVal2
Shr cx,6
Sub cx,ax
Inc cx
Js @Exit
Jcxz @Exit
Mov bx,Count
Mov dx,bx
Shl bx,6
Add bh,dl
Add bx,ax
Mov di,bx
Mov ax,pVal1
Mov si,dPhi
Mov dx,tVal1
Push bp
Mov bp,dTheta
Push ds
Lds bx,EnvMap
Shr cx,1
Jnc @SkipSingle
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
@SkipSingle:
Xor ch,ch
Jcxz @SkipLoop
@Looper:
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
Dec cl
Jnz @Looper
@SkipLoop:
Pop ds
Pop bp
@Exit:
End;
{ ***** End HLine ***** }
xVal1 := xVal1 + xStep1;
xVal2 := xVal2 + xStep2;
pVal1 := pVal1 + pStep1;
tVal1 := tVal1 + tStep1;
End;
tVal1 := tVal1 - tStep1;
pVal1 := pVal1 - pStep1;
xVal1 := xVal1 - xStep1;
xStep2 := (xBot-xMid) Shl 6 Div (yBot-yMid+1);
For Count := yMid to yBot do
Begin
{ ***** HLine *****}
Asm
Mov ax,Segment
Mov es,ax
Mov ax,xVal1
Shr ax,6
Mov cx,xVal2
Shr cx,6
Sub cx,ax
Inc cx
Js @Exit
Jcxz @Exit
Mov bx,Count
Mov dx,bx
Shl bx,6
Add bh,dl
Add bx,ax
Mov di,bx
Mov ax,pVal1
Mov si,dPhi
Mov dx,tVal1
Push bp
Mov bp,dTheta
Push ds
Lds bx,EnvMap
Shr cx,1
Jnc @SkipSingle
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
@SkipSingle:
Xor ch,ch
Jcxz @SkipLoop
@Looper:
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
Mov bh,ah
Mov bl,dh
Mov ch,ds:[bx]
Mov es:[di],ch
Add ax,si
Add dx,bp
Inc di
Dec cl
Jnz @Looper
@SkipLoop:
Pop ds
Pop bp
@Exit:
End;
{ ***** End HLine ***** }
xVal1 := xVal1 + xStep1;
xVal2 := xVal2 + xStep2;
pVal1 := pVal1 + pStep1;
tVal1 := tVal1 + tStep1;
End;
End;
End;
Procedure PhongClipPolygon(x1, y1, x2, y2, x3, y3, t1, p1, t2, p2, t3, p3, PgSeg : Integer; EMap : Pointer);
Type
tFlatClip = Record
x, y, x1, y1 : Integer;
t, p, t1, p1 : Integer;
End;
Var
FlatList : Array[0..7] of tFlatClip;
NumVert : Integer;
Count : Integer;
ClipVert : Integer;
V1, V2 : Integer;
Begin
EnvMap := EMap;
If (((X1 >= MinX) and (X1 <= MaxX)) and ((Y1 >= MinY) and (Y1 <= MaxY)) and
((X2 >= MinX) and (X2 <= MaxX)) and ((Y2 >= MinY) and (Y2 <= MaxY))) and
((X3 >= MinX) and (X3 <= MaxX)) and ((Y3 >= MinY) and (Y3 <= MaxY))
Then Begin
PhongPoly(X1, Y1, X2, Y2, X3, Y3, p1, t1, p2, t2, p3, t3, PgSeg);
Exit;
End;
FlatList[0].x := X1;
FlatList[0].y := Y1;
FlatList[0].t := t1;
FlatList[0].p := p1;
FlatList[1].x := X2;
FlatList[1].y := Y2;
FlatList[1].t := t2;
FlatList[1].p := p2;
FlatList[2].x := X3;
FlatList[2].y := Y3;
FlatList[2].t := t3;
FlatList[2].p := p3;
NumVert := 3;
ClipVert := 0;
{ Clip against left side }
V1 := NumVert - 1;
For Count := 0 to (NumVert-1) do
Begin
If (FlatList[V1].x >= MinX) and (FlatList[Count].x >= MinX)
Then Begin
FlatList[ClipVert].x1 := FlatList[Count].x;
FlatList[ClipVert].y1 := FlatList[Count].y;
FlatList[ClipVert].t1 := FlatList[Count].t;
FlatList[ClipVert].p1 := FlatList[Count].p;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].x >= MinX) and (FlatList[Count].x < MinX)
Then Begin
FlatList[ClipVert].x1 := MinX;
FlatList[ClipVert].y1 := (FlatList[Count].y-FlatList[V1].y)*(MinX-FlatList[v1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].y;
FlatList[ClipVert].t1 := (FlatList[Count].t-FlatList[V1].t)*(MinX-FlatList[v1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].t;
FlatList[ClipVert].p1 := (FlatList[Count].p-FlatList[V1].p)*(MinX-FlatList[v1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].p;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].x < MinX) and (FlatList[Count].x >= MinX)
Then Begin
FlatList[ClipVert].x1 := MinX;
FlatList[ClipVert].y1 := (FlatList[Count].y-FlatList[V1].y)*(MinX-FlatList[V1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].y;
FlatList[ClipVert].t1 := (FlatList[Count].t-FlatList[V1].t)*(MinX-FlatList[V1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].t;
FlatList[ClipVert].p1 := (FlatList[Count].p-FlatList[V1].p)*(MinX-FlatList[V1].x)
Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].p;
ClipVert := ClipVert + 1;
FlatList[ClipVert].x1 := FlatList[Count].x;
FlatList[ClipVert].y1 := FlatList[Count].y;
FlatList[ClipVert].t1 := FlatList[Count].t;
FlatList[ClipVert].p1 := FlatList[Count].p;
ClipVert := ClipVert + 1;
End;
V1 := Count;
End;
NumVert := ClipVert;
ClipVert := 0;
{ Clip against Right side }
V1 := NumVert - 1;
For Count := 0 to (NumVert-1) do
Begin
If (FlatList[v1].x1 <= MaxX) and (FlatList[Count].x1 <= MaxX)
Then Begin
FlatList[ClipVert].x := FlatList[Count].x1;
FlatList[ClipVert].y := FlatList[Count].y1;
FlatList[ClipVert].t := FlatList[Count].t1;
FlatList[ClipVert].p := FlatList[Count].p1;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].x1 <= MaxX) and (FlatList[Count].x1 > MaxX)
Then Begin
FlatList[ClipVert].x := MaxX;
FlatList[ClipVert].y := (FlatList[Count].y1-FlatList[V1].y1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].y1;
FlatList[ClipVert].t := (FlatList[Count].t1-FlatList[V1].t1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].t1;
FlatList[ClipVert].p := (FlatList[Count].p1-FlatList[V1].p1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].p1;
ClipVert := ClipVert + 1;
End;
If (FlatList[v1].x1 > MaxX) and (FlatList[Count].x1 <= MaxX)
Then Begin
FlatList[ClipVert].x := MaxX;
FlatList[ClipVert].y := (FlatList[Count].y1-FlatList[V1].y1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].y1;
FlatList[ClipVert].t := (FlatList[Count].t1-FlatList[V1].t1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].t1;
FlatList[ClipVert].p := (FlatList[Count].p1-FlatList[V1].p1)*(MaxX-FlatList[v1].x1)
Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].p1;
ClipVert := ClipVert + 1;
FlatList[ClipVert].x := FlatList[Count].x1;
FlatList[ClipVert].y := FlatList[Count].y1;
FlatList[ClipVert].t := FlatList[Count].t1;
FlatList[ClipVert].p := FlatList[Count].p1;
ClipVert := ClipVert + 1;
End;
v1 := Count;
End;
NumVert := ClipVert;
ClipVert := 0;
{ Clip against top edge }
V1 := NumVert - 1;
For Count := 0 to (NumVert-1) do
Begin
If (FlatList[V1].y >= MinY) and (FlatList[Count].y >= MinY)
Then Begin
FlatList[ClipVert].x1 := FlatList[Count].x;
FlatList[ClipVert].y1 := FlatList[Count].y;
FlatList[ClipVert].t1 := FlatList[Count].t;
FlatList[ClipVert].p1 := FlatList[Count].p;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].y >= MinY) and (FlatList[Count].y < MinY)
Then Begin
FlatList[ClipVert].x1 := (MinY-FlatList[V1].y)*(FlatList[Count].x-FlatList[V1].x)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].x;
FlatList[ClipVert].t1 := (MinY-FlatList[V1].y)*(FlatList[Count].t-FlatList[V1].t)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].t;
FlatList[ClipVert].p1 := (MinY-FlatList[V1].y)*(FlatList[Count].p-FlatList[V1].p)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].p;
FlatList[ClipVert].y1 := MinY;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].y < MinY) and (FlatList[Count].y >= MinY)
Then Begin
FlatList[ClipVert].x1 := (MinY-FlatList[V1].y)*(FlatList[Count].x-FlatList[V1].x)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].x;
FlatList[ClipVert].t1 := (MinY-FlatList[V1].y)*(FlatList[Count].t-FlatList[V1].t)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].t;
FlatList[ClipVert].p1 := (MinY-FlatList[V1].y)*(FlatList[Count].p-FlatList[V1].p)
Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].p;
FlatList[ClipVert].y1 := MinY;
ClipVert := ClipVert + 1;
FlatList[ClipVert].x1 := FlatList[Count].x;
FlatList[ClipVert].y1 := FlatList[Count].y;
FlatList[ClipVert].t1 := FlatList[Count].t;
FlatList[ClipVert].p1 := FlatList[Count].p;
ClipVert := ClipVert + 1;
End;
V1 := Count;
End;
NumVert := ClipVert;
ClipVert := 0;
V1 := NumVert - 1;
For Count := 0 to (NumVert-1) do
Begin
If (FlatList[V1].y1 <= MaxY) and (FlatList[Count].y1 <= MaxY)
Then Begin
FlatList[ClipVert].x := FlatList[Count].x1;
FlatList[ClipVert].y := FlatList[Count].y1;
FlatList[ClipVert].t := FlatList[Count].t1;
FlatList[ClipVert].p := FlatList[Count].p1;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].y1 <= MaxY) and (FlatList[Count].y1 > MaxY)
Then Begin
FlatList[ClipVert].x := (MaxY-FlatList[V1].y1)*(FlatList[Count].x1-FlatList[V1].x1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].x1;
FlatList[ClipVert].t := (MaxY-FlatList[V1].y1)*(FlatList[Count].t1-FlatList[V1].t1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].t1;
FlatList[ClipVert].p := (MaxY-FlatList[V1].y1)*(FlatList[Count].p1-FlatList[V1].p1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].p1;
FlatList[ClipVert].y := MaxY;
ClipVert := ClipVert + 1;
End;
If (FlatList[V1].y1 > MaxY) and (FlatList[Count].y1 <= MaxY)
Then Begin
FlatList[ClipVert].x := (MaxY-FlatList[V1].y1)*(FlatList[Count].x1-FlatList[V1].x1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].x1;
FlatList[ClipVert].t := (MaxY-FlatList[V1].y1)*(FlatList[Count].t1-FlatList[V1].t1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].t1;
FlatList[ClipVert].p := (MaxY-FlatList[V1].y1)*(FlatList[Count].p1-FlatList[V1].p1)
Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].p1;
FlatList[ClipVert].y := MaxY;
ClipVert := ClipVert + 1;
FlatList[ClipVert].x := FlatList[Count].x1;
FlatList[ClipVert].y := FlatList[Count].y1;
FlatList[ClipVert].t := FlatList[Count].t1;
FlatList[ClipVert].p := FlatList[Count].p1;
ClipVert := ClipVert + 1;
End;
V1 := Count;
End;
NumVert := ClipVert;
V1 := 1;
V2 := 2;
{ Now draw the polygons }
For Count := 0 to (NumVert - 3) do
Begin
PhongPoly(FlatList[0].x, FlatList[0].y,
FlatList[V1].x, FlatList[V1].y,
FlatList[V2].x, FlatList[V2].y,
FlatList[0].p, FlatList[0].t,
FlatList[V1].p, FlatList[V1].t,
FlatList[V2].p, FlatList[V2].t, PgSeg);
V1 := V2;
V2 := V2 + 1;
End;
End;
End.